﻿using _8.test;
using DevExpress.XtraBars.Docking2010.Views;
using DevExpress.XtraBars.Docking2010.Views.Widget;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using XCI.Extensions;
using XCI.Helper;

namespace XCI.Windows
{
    /// <summary>
    /// 部件帮助类
    /// </summary>
    public class WidgetManage
    {
        private WidgetView _widgetView;
        private List<WidgetItem> _widgetItems;
        private string _code;
        private string _dataLocalPath;
        private string _dataServerPath;
        private string _settingLocalPath;
        private string _settingServerPath;
        //private string _mode;//当前模式 design:设计模式
        private Random _random = new Random();

        public WidgetManage(WidgetView widgetView, string code)
        {
            if (string.IsNullOrEmpty(code)) throw new ArgumentNullException(nameof(code));
            _widgetView = widgetView ?? throw new ArgumentNullException(nameof(widgetView));

            InitWidgetView();

            _code = code;
            _dataLocalPath = GetLocalPath(GetDataFileName());
            _dataServerPath = GetServerPath(GetDataFileName());
            _settingLocalPath = GetLocalPath(GetSettingFileName());
            _settingServerPath = GetServerPath(GetSettingFileName());
        }

        public WidgetView WidgetViewObject => _widgetView;

        public List<WidgetItem> WidgetData => _widgetItems;

        private void InitWidgetView()
        {
            if (_widgetView.StackGroups.Count == 0)
            {
                StackGroup stackGroup1 = new StackGroup();
                StackGroup stackGroup2 = new StackGroup();
                StackGroup stackGroup3 = new StackGroup();
                _widgetView.StackGroups.AddRange(new[] { stackGroup1, stackGroup2, stackGroup3 });
            }
            if (_widgetView.Rows.Count == 0 && _widgetView.Columns.Count == 0)
            {
                ColumnDefinition columnDefinition1 = new ColumnDefinition();
                ColumnDefinition columnDefinition2 = new ColumnDefinition();
                ColumnDefinition columnDefinition3 = new ColumnDefinition();
                RowDefinition rowDefinition1 = new RowDefinition();
                RowDefinition rowDefinition2 = new RowDefinition();
                RowDefinition rowDefinition3 = new RowDefinition();
                _widgetView.Columns.AddRange(new[] { columnDefinition1, columnDefinition2, columnDefinition3 });
                _widgetView.Rows.AddRange(new [] { rowDefinition1, rowDefinition2, rowDefinition3 });
            }

            _widgetView.QueryControl += _widgetView_QueryControl;
            _widgetView.DocumentClosed += _widgetView_DocumentClosed;
        }

        public void Load()
        {
            //var dataMd5 = string.Empty;
            //if (File.Exists(_dataLocalPath)) dataMd5 = StringHelper.Md5File(_dataLocalPath);
            //FileUploadService.Instance.Download(_dataServerPath, _dataLocalPath, dataMd5);

            //var settingMd5 = string.Empty;
            //if (File.Exists(_settingLocalPath)) settingMd5 = StringHelper.Md5File(_settingLocalPath);
            //FileUploadService.Instance.Download(_settingServerPath, _settingLocalPath, settingMd5);

            LoadWidgetObject();
            LoadWidgetSetting();
        }

        private void LoadWidgetObject()
        {
            if (File.Exists(_dataLocalPath))
            {
                _widgetItems = JsonHelper.DeserializeByPath<List<WidgetItem>>(_dataLocalPath);
            }
            if (_widgetItems == null)
            {
                _widgetItems = new List<WidgetItem>();
            }
        }

        private void LoadWidgetSetting()
        {
            try
            {
                _widgetView.BeginUpdateAnimation();
                _widgetView.FlowLayoutProperties.FlowLayoutItems.Clear();
                _widgetView.FreeLayoutProperties.FreeLayoutItems.Clear();
                for (int i = 0; i < _widgetView.StackGroups.Count; i++)
                {
                    _widgetView.StackGroups[i].Items.Clear();
                }
                _widgetView.Documents.Clear();

                
                foreach (var item in _widgetItems)
                {
                    if (!item.Visable) continue;

                    try
                    {
                        item.WidgetInstance = ObjectHelper.CreateInstance<IWidget>(item.ControlType);
                        item.DocumentInstance = item.WidgetInstance.CreateDocument();
                        item.DocumentInstance.ControlName = item.Id;
                        item.DocumentInstance.ControlTypeName = item.ControlType;
                        if (string.IsNullOrEmpty(item.DocumentInstance.Caption))
                        {
                            item.DocumentInstance.Caption = item.Name;
                        }
                        if (string.IsNullOrEmpty(item.DocumentInstance.ControlName))
                        {
                            item.DocumentInstance.ControlName = item.DocumentInstance.Caption;
                        }
                        _widgetView.Documents.Add(item.DocumentInstance);
                    }
                    catch (Exception e)
                    {
                        DebugHelper.Catch(e);
                    }
                }
                if (File.Exists(_settingLocalPath))
                {
                    _widgetView.RestoreLayoutFromXml(_settingLocalPath);
                }
            }
            finally
            {
                _widgetView.EndUpdateAnimation();
            }
        }

        /// <summary>
        /// 检测配置是否存在
        /// </summary>
        public bool Exists()
        {
            return File.Exists(GetLocalPath(GetDataFileName()));
        }

        public bool AddItem(WidgetItem item)
        {
            if (item == null) return false;
            if (_widgetItems.Any(p => p.Id.Equals(item.Id))) return false;
            _widgetItems.Add(item);
            return true;
        }

        public void RemoveItem(string id)
        {
            if (string.IsNullOrEmpty(id)) return;
            _widgetItems.Delete(p => p.Id.Equals(id));
        }

        public void Reset()
        {
            if (File.Exists(_dataLocalPath))
            {
                File.Delete(_dataLocalPath);
            }

            if (File.Exists(_settingLocalPath))
            {
                File.Delete(_settingLocalPath);
            }
            Load();
        }

        public BaseDocument GetDocumentById(string id)
        {
            var item = _widgetItems.FirstOrDefault(p => p.Id.Equals(id));
            if (item != null)
            {
                return item.DocumentInstance;
            }
            return null;
        }

        /// <summary>
        /// 设计
        /// </summary>
        public void Design()
        {
            //_mode = "design";
            var settingFrom = new FrmWidgetSetting(_code);
            settingFrom.ShowDialog();
            settingFrom.Dispose();
        }

        /// <summary>
        /// 表格布局混合
        /// </summary>
        public void TableLayoutMix()
        {
            try
            {
                _widgetView.BeginUpdateAnimation();
                var points = new List<Point>();
                for (int i = 0; i < _widgetView.Rows.Count; i++)
                {
                    for (int j = 0; j < _widgetView.Columns.Count; j++)
                    {
                        points.Add(new Point(i, j));
                    }
                }
                foreach (Document document in _widgetView.Documents)
                {
                    Point newLocation = points[_random.Next(points.Count)];
                    document.RowIndex = newLocation.Y;
                    document.ColumnIndex = newLocation.X;
                    points.Remove(newLocation);
                }
            }
            finally
            {
                _widgetView.EndUpdateAnimation();
            }
        }

        /// <summary>
        /// 流式布局混合
        /// </summary>
        public void FlowLayoutMix()
        {
            try
            {
                _widgetView.BeginUpdateAnimation();
                for (int i = 0; i < _widgetView.FlowLayoutProperties.FlowLayoutItems.Count; i++)
                {
                    var index = _random.Next(_widgetView.Documents.Count);
                    if (i == index) continue;
                    var document = _widgetView.FlowLayoutProperties.FlowLayoutItems[i];
                    _widgetView.FlowLayoutProperties.FlowLayoutItems.Remove(document);
                    _widgetView.FlowLayoutProperties.FlowLayoutItems.Insert(index, document);
                }
            }
            finally
            {
                _widgetView.EndUpdateAnimation();
            }
        }

        /// <summary>
        /// 堆栈布局混合
        /// </summary>
        public void StackLayoutMix()
        {
            try
            {
                _widgetView.BeginUpdateAnimation();
                foreach (DevExpress.XtraBars.Docking2010.Views.Widget.Document document in _widgetView.Documents)
                {
                    StackGroup oldGroup = document.Parent;
                    if (oldGroup != null)
                    {
                        oldGroup.Items.Remove(document);
                    }
                    var randomIndex = _random.Next(_widgetView.StackGroups.Count);
                    _widgetView.StackGroups[randomIndex].Items.Add(document);
                }
            }
            finally
            {
                _widgetView.EndUpdateAnimation();
            }
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        public void Save()
        {
            IOHelper.CreateDirectoryByPath(_dataLocalPath);

            JsonHelper.SerializeByPath(_dataLocalPath, _widgetItems);
            _widgetView.SaveLayoutToXml(_settingLocalPath);

            //FileUploadService.Instance.UploadFileAsMessage(_settingServerPath, _dataLocalPath);
            //FileUploadService.Instance.UploadFileAsMessage(_settingServerPath, _settingLocalPath);
        }

        private void _widgetView_QueryControl(object sender, DevExpress.XtraBars.Docking2010.Views.QueryControlEventArgs e)
        {
            if (string.IsNullOrEmpty(e.Document.ControlTypeName))
            {
                e.Control = new Control();
                return;
            }

            var widget = _widgetItems.FirstOrDefault(p => p.Id.Equals(e.Document.ControlName));
            if (widget != null)
            {
                e.Control = widget.WidgetInstance.CreateInstance(widget.ParamMap ?? new Dictionary<string, string>());
            }
        }

        private void _widgetView_DocumentClosed(object sender, DevExpress.XtraBars.Docking2010.Views.DocumentEventArgs e)
        {
            var widget = _widgetItems.FirstOrDefault(p => p.Id.Equals(e.Document.ControlName));
            if (widget != null)
            {
                widget.Visable = false;
            }
        }

        /// <summary>
        /// 获取数据文件名称
        /// </summary>
        private string GetDataFileName()
        {
            return $"{_code}.json";
        }

        /// <summary>
        /// 获取配置文件名称
        /// </summary>
        private string GetSettingFileName()
        {
            return $"{_code}.xml";
        }

        /// <summary>
        /// 获取服务端文件路径
        /// </summary>
        /// <param name="name">文件名称</param>
        private string GetServerPath(string name)
        {
            return $"/res/widget/{name}";
        }

        /// <summary>
        /// 获取本地文件路径
        /// </summary>
        /// <param name="name">文件名称</param>
        /// <returns>返回完整文件路径</returns>
        private string GetLocalPath(string name)
        {
            return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Widget", name);
        }
    }
}